﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using Microsoft.TeamFoundation.Client;
using Microsoft.TeamFoundation.WorkItemTracking.Client;
using Microsoft.TeamFoundation.Build.Client;
using Microsoft.TeamFoundation.VersionControl.Client;
using Microsoft.TeamFoundation.Framework.Client;
using Microsoft.TeamFoundation.Server;

public class TfsCollection
{
    private TfsTeamProjectCollection _tpc;
    private TswaClientHyperlinkService _hyperlink;
    private IGroupSecurityService _groupSecurity;
    private VersionControlServer _versionControl;
    private WorkItemStore _workItemStore;
    private ILocationService _locationService;
    private IBuildServer _buildServer;
    private TfsWorkItems _workItems;

    public TfsCollection(string tfsServerUri, string tfsCollectionName)
    {
        Uri tfsProjectCollectionUri = GetTfsProjectCollectionUri(tfsServerUri, tfsCollectionName);
        _tpc = TfsTeamProjectCollectionFactory.GetTeamProjectCollection(tfsProjectCollectionUri);
    }

    private T GetService<T>(ref T prop)
    {
        if (prop == null)
            prop = _tpc.GetService<T>();
        return prop;
    }

    public IBuildServer BuilderServer
    {
        get { return GetService<IBuildServer>(ref _buildServer); }
    }

    public IGroupSecurityService GroupSecurityService
    {
        get { return GetService<IGroupSecurityService>(ref _groupSecurity); }
    }

    public TswaClientHyperlinkService HyperlinkService
    {
        get { return GetService<TswaClientHyperlinkService>(ref _hyperlink); }
    }

    public ILocationService LocationService
    {
        get { return GetService<ILocationService>(ref _locationService); }
    }

    public VersionControlServer VersionControlServer
    {
        get { return GetService<VersionControlServer>(ref _versionControl); }
    }

    public TfsWorkItems WorkItems
    {
        get
        {
            if (_workItems == null)
                _workItems = new TfsWorkItems(this);

            return _workItems;
        }
    }

    public WorkItemStore WorkItemStore
    {
        get { return GetService<WorkItemStore>(ref _workItemStore); }
    }

    public List<string> GetUsers()
    {
        List<string> users = new List<string>();

        Identity allSids = GroupSecurityService.ReadIdentity(SearchFactor.AccountName, "Project Collection Valid Users", QueryMembership.Expanded);
        Identity[] allUsers = GroupSecurityService.ReadIdentities(SearchFactor.Sid, allSids.Members, QueryMembership.None);
        foreach (Identity identity in allUsers)
        {
            if (identity.Type == IdentityType.WindowsUser)
            {
                users.Add(identity.DisplayName);
            }
        }

        users.Sort();
        return users;
    }

    public List<string> GetIterations(string tfsProjectName)
    {
        Project project = WorkItemStore.Projects[tfsProjectName];

        List<string> areaPathList = new List<string>();
        ExpandNodes(project.IterationRootNodes, areaPathList);
        return areaPathList;
    }

    public List<string> GetAreas(string tfsProjectName)
    {
        Project project = WorkItemStore.Projects[tfsProjectName];

        List<string> areaPathList = new List<string>();
        ExpandNodes(project.AreaRootNodes, areaPathList);
        return areaPathList;
    }

    private void ExpandNodes(NodeCollection nodeCollection, List<string> expandedNodesList)
    {
        foreach (Node node in nodeCollection)
        {
            expandedNodesList.Add(node.Path);
            if (node.HasChildNodes)
            {
                ExpandNodes(node.ChildNodes, expandedNodesList);
            }
        }
    }

    private Uri GetTfsProjectCollectionUri(string serverUrl, string collectionName)
    {
        UriBuilder tfsProjectCollectionUriBuilder = new UriBuilder(serverUrl);
        List<string> paths = new List<string>(tfsProjectCollectionUriBuilder.Path.Split(new char[] { '/' }, StringSplitOptions.RemoveEmptyEntries));
        paths.Add(collectionName);
        tfsProjectCollectionUriBuilder.Path = string.Join("/", paths);
        return tfsProjectCollectionUriBuilder.Uri;
    }
}